// RenderWindow.cpp

#include "stdafx.h"
#include "World.h"
#include "RenderWindow.h"

RenderWindow::RenderWindow()
{
	m_pxBM=NULL;
};

RenderWindow::~RenderWindow()
{
	if (m_xNet.m_bIsRunning)
	{
		m_xNet.Shut();
	};
	delete m_pxBM;
};

long RenderWindow::StaticMainWndProc(HWND p_hWnd,int p_iMessage,
									 int p_wWParam,int p_iLParam)
{
	RenderWindow* pxThis=NULL;
#pragma warning(push)
#pragma warning(disable:4312)
#if defined(_X86_)
	pxThis=(RenderWindow*)::GetWindowLong(p_hWnd,GWL_USERDATA);
#elif defined(_AMD64_)
	pxThis=(RenderWindow*)::GetWindowLong(p_hWnd,GWLP_USERDATA);
#endif
#pragma warning(pop)

	if(pxThis==NULL)
	{
		return (long)::DefWindowProc(p_hWnd,p_iMessage,p_wWParam,p_iLParam);
	};

	return pxThis->MainWndProc(p_iMessage,p_wWParam,p_iLParam);
};

long RenderWindow::MainWndProc(int p_iMessage,int p_wWParam,int p_iLParam)
{
	if(p_iMessage==WM_QUIT)
	{
		m_bQuit=true;
		return 0;
	};
	if(p_iMessage==WM_SYSCOMMAND)
	{
		if(p_wWParam==SC_CLOSE)
		{
			m_bQuit=true;
			return 0;
		};
	};
	if(p_iMessage==WM_ACTIVATE)
	{
		m_bActive=(LOWORD(p_wWParam)!=WA_INACTIVE);
		return 0;
	};
	if(p_iMessage==WM_PAINT)
	{
		PAINTSTRUCT xPS;
		HDC hDC;
		hDC=::BeginPaint(m_hWnd,&xPS);
		if((m_iW>0)&&(m_iH>0)&&(m_pxBM))
		{
			HDC hDCBitmap=::CreateCompatibleDC(hDC);
			::SelectObject(hDCBitmap,m_pxBM->m_hDIB);
			{
				::BitBlt(hDC,0,0,m_pxBM->m_iW,m_pxBM->m_iH,hDCBitmap,0,0,SRCCOPY);
			};
			::DeleteDC(hDCBitmap);
		};
		::EndPaint(m_hWnd,&xPS);
		return 0;
	};
	if(p_iMessage==WM_WINDOWPOSCHANGED)
	{
		RECT xR;
		::GetClientRect(m_hWnd,&xR);
		OnResize(xR.right-xR.left,xR.bottom-xR.top);
	};
	if(p_iMessage==WM_CHAR)
	{
		OnChar((char)p_wWParam);
		return 0;
	};
	return (long)::DefWindowProc(m_hWnd,p_iMessage,p_wWParam,p_iLParam);
};

bool RenderWindow::Init(HINSTANCE p_hInstance)
{
	m_hInstance=p_hInstance;
	m_bQuit=false;
	m_bActive=true;

	m_xScoreFont.Init("Tahoma",-14);

	m_xWndClass.lpszClassName=TEXT("ptRenderWindow");
	m_xWndClass.hInstance=m_hInstance;
	m_xWndClass.hIcon=::LoadIcon(NULL,IDI_EXCLAMATION);
	m_xWndClass.hCursor=::LoadCursor(NULL,IDC_ARROW);
	m_xWndClass.lpszMenuName=NULL;
	m_xWndClass.hbrBackground=(HBRUSH)(COLOR_BACKGROUND);
	m_xWndClass.lpfnWndProc=(WNDPROC)StaticMainWndProc;
	m_xWndClass.style=CS_OWNDC|CS_VREDRAW|CS_HREDRAW;
	m_xWndClass.cbClsExtra=0;
	m_xWndClass.cbWndExtra=0;

	::RegisterClass(&m_xWndClass);

	m_hWnd=::CreateWindowEx(0,TEXT("ptRenderWindow"),TEXT("Test"),
		WS_OVERLAPPED|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_VISIBLE|WS_SYSMENU
		//WS_POPUP|WS_THICKFRAME
		,110,10,400,400,0,0,m_hInstance,0);

#pragma warning(push)
#pragma warning(disable:4311)

#if defined(_X86_)
	::SetWindowLong(m_hWnd,GWL_USERDATA,(DWORD)this);
#elif defined(_AMD64_)
	::SetWindowLong(m_hWnd,GWLP_USERDATA,(LONG)this);
#endif

#pragma warning(pop)

	::ShowWindow(m_hWnd,SW_SHOWNORMAL);

	{
		RECT xR;
		::GetClientRect(m_hWnd,&xR);
		OnResize(xR.right-xR.left,xR.bottom-xR.top);
	};

	return true;
};

void RenderWindow::Shut()
{
	::CloseWindow(m_hWnd);
};

bool RenderWindow::MessagePump(bool p_bFull)
{
	MSG xMsg;
	bool bRet=true;
	bool bDone=false;
	while((!bDone)&&(!m_bQuit))
	{
		if(!p_bFull){bDone=true;};
		if(::PeekMessage(&xMsg,m_hWnd,0,0,PM_NOREMOVE))
		{
			if(::GetMessage(&xMsg,m_hWnd,0,0))
			{
				::TranslateMessage(&xMsg);
				::DispatchMessage(&xMsg);
			}
			else
			{
				bDone=true;
				bRet=false;
			};
		}
		else
		{
			::Sleep(20);
			int iCurTick=::GetTickCount();
			if (m_xNet.m_bIsRunning)
			{
				m_xNet.Recv();
			};

			if(abs(iCurTick-m_iLastGameTick)>25)
			{
				m_iLastGameTick=iCurTick;
				m_xWorld.Update();
				if (m_xNet.m_bIsRunning)
				{
					m_xNet.Broadcast();
				};
			};	
			Render();
		};
	};
	return bRet&&(!m_bQuit);
};

void RenderWindow::OnResize(int p_iW,int p_iH)
{
	char acT[256];
	sprintf(acT,"Size: %d x %d",p_iW,p_iH);
	::SetWindowTextA(m_hWnd,acT);
	m_iW=p_iW;
	m_iH=p_iH;
	delete m_pxBM;
	m_pxBM=new Bitmap();
	m_pxBM->Init(m_iW,m_iH);
};

void RenderWindow::Render()
{
	m_pxBM->Clear(0);
	m_pxBM->DrawTextA(10,10,"Car game",0x808080);
	m_xWorld.Render(m_pxBM);
	::InvalidateRect(m_hWnd,NULL,FALSE);
};

void RenderWindow::OnChar(char p_cKey)
{
	if(p_cKey=='n')
	{
		m_xNet.Init(&m_xWorld);
		m_xNet.Scan();
		m_xNet.ScanExternals();
		printf("Scan start.\n");
	};
	if(p_cKey=='s')
	{
		printf("Scan start.\n");
		m_xNet.Scan();
	};
};












